package com.imis.base.util.table.service.impl;

import com.imis.base.constant.CommonConstant;
import com.imis.base.constant.DataBaseConstant;
import com.imis.base.util.ConvertUtils;
import com.imis.base.util.table.model.ColumnMeta;
import com.imis.base.util.table.service.IDataBaseTableHandleService;
import com.imis.module.online.table.model.po.TableIndex;

/**
 * <p>
 * DataBaseTableOracleHandleServiceImpl<br>
 * Oracle 数据库表处理服务 实现
 * 语句结尾不能使用 ';'
 * </p>
 *
 * @author XinLau
 * @version 1.0
 * @since 2020年09月28日 17:36
 */
public class DataBaseTableOracleHandleServiceImpl implements IDataBaseTableHandleService {

    /**
     * 获取添加字段描述
     *
     * @param formColumnMeta - 前端表单
     * @return String - SQL语句
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/10 14:17
     */
    private String getAddFieldDesc(final ColumnMeta formColumnMeta) {
        StringBuilder sql = new StringBuilder();
        if (DataBaseConstant.STRING.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.VARCHAR2).append(DataBaseConstant.LEFT_BRACKET).append(formColumnMeta.getColumnSize()).append(DataBaseConstant.RIGHT_BRACKET);
        } else if (DataBaseConstant.DATE_.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.DATE_);
        } else if (DataBaseConstant.INT.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.NUMBER_).append(DataBaseConstant.LEFT_BRACKET).append(formColumnMeta.getColumnSize()).append(DataBaseConstant.RIGHT_BRACKET);
        } else if (DataBaseConstant.DOUBLE.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.NUMBER_).append(DataBaseConstant.LEFT_BRACKET).append(formColumnMeta.getColumnSize()).append(DataBaseConstant.COMMA).append(formColumnMeta.getDecimalDigits()).append(DataBaseConstant.RIGHT_BRACKET);
        } else if (DataBaseConstant.BIG_DECIMAL_.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.NUMBER_).append(DataBaseConstant.LEFT_BRACKET).append(formColumnMeta.getColumnSize()).append(DataBaseConstant.COMMA).append(formColumnMeta.getDecimalDigits()).append(DataBaseConstant.RIGHT_BRACKET);
        } else if (DataBaseConstant.TEXT_.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.CLOB_);
        } else if (DataBaseConstant.BLOB_.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.BLOB_).append(DataBaseConstant.SPACE);
        }
        sql.append((ConvertUtils.isNotEmpty(formColumnMeta.getColumnDefaultValue()) ? DataBaseConstant.SQL_DEFAULT + formColumnMeta.getColumnDefaultValue() : DataBaseConstant.SPACE));
        sql.append((CommonConstant.TO_UPPER_CASE_Y.equals(formColumnMeta.getIsNullable()) ? DataBaseConstant.SQL_NULL : DataBaseConstant.SQL_NOT_NULL));
        return sql.toString();
    }

    /**
     * 获取更新字段描述
     *
     * @param formColumnMeta - 前端表单
     * @param dataColumnMeta - 数据库表
     * @return String - SQL语句
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/10 14:17
     */
    private String getUpdateFieldDesc(final ColumnMeta formColumnMeta, ColumnMeta dataColumnMeta) {
        StringBuilder sql = new StringBuilder();
        String isnull = CommonConstant.EMPTY;
        // Oracle 对于是否为空必须跟原来的比对
        if (!dataColumnMeta.getIsNullable().equals(formColumnMeta.getIsNullable())) {
            isnull = (CommonConstant.TO_UPPER_CASE_Y.equals(formColumnMeta.getIsNullable()) ? DataBaseConstant.SQL_NULL : DataBaseConstant.SQL_NOT_NULL);
        }
        if (DataBaseConstant.STRING.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.VARCHAR2).append(DataBaseConstant.LEFT_BRACKET)
                    .append(formColumnMeta.getColumnSize()).append(DataBaseConstant.RIGHT_BRACKET).append(DataBaseConstant.SPACE).append(isnull);
        } else if (DataBaseConstant.DATE_.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.DATE_).append(DataBaseConstant.SPACE).append(isnull);
        } else if (DataBaseConstant.INT.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.NUMBER_).append(DataBaseConstant.LEFT_BRACKET)
                    .append(formColumnMeta.getColumnSize()).append(DataBaseConstant.RIGHT_BRACKET).append(DataBaseConstant.SPACE).append(isnull);
        } else if (DataBaseConstant.DOUBLE.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.NUMBER_).append(DataBaseConstant.LEFT_BRACKET).append(formColumnMeta.getColumnSize())
                    .append(DataBaseConstant.COMMA).append(formColumnMeta.getDecimalDigits()).append(DataBaseConstant.RIGHT_BRACKET).append(DataBaseConstant.SPACE).append(isnull);
        } else if (DataBaseConstant.BIG_DECIMAL_.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.NUMBER_).append(DataBaseConstant.LEFT_BRACKET).append(formColumnMeta.getColumnSize())
                    .append(DataBaseConstant.COMMA).append(formColumnMeta.getDecimalDigits()).append(DataBaseConstant.RIGHT_BRACKET).append(DataBaseConstant.SPACE).append(isnull);
        } else if (DataBaseConstant.BLOB_.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.CLOB_).append(DataBaseConstant.SPACE).append(isnull);
        } else if (DataBaseConstant.TEXT_.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.BLOB_).append(DataBaseConstant.SPACE).append(isnull);
        }
        sql.append((ConvertUtils.isNotEmpty(formColumnMeta.getColumnDefaultValue()) ? DataBaseConstant.SQL_DEFAULT + formColumnMeta.getColumnDefaultValue() : DataBaseConstant.SPACE));
        sql.append(isnull);
        return sql.toString();
    }

    @Override
    public String getAddColumnSql(final ColumnMeta columnMeta) {
        return DataBaseConstant.SQL_ADD + getAddFieldDesc(columnMeta) + DataBaseConstant.EMPTY;
    }

    @Override
    public String getReNameFieldName(final ColumnMeta columnMeta) {
        return DataBaseConstant.SQL_RENAME + DataBaseConstant.SQL_COLUMN + columnMeta.getOldColumnName() + DataBaseConstant.SQL_TO + columnMeta.getColumnName() + DataBaseConstant.EMPTY;
    }

    @Override
    public String getUpdateColumnSql(final ColumnMeta formColumnMeta, final ColumnMeta dataColumnMeta) {
        return DataBaseConstant.SQL_MODIFY + getUpdateFieldDesc(formColumnMeta, dataColumnMeta) + DataBaseConstant.EMPTY;
    }

    @Override
    public String getMatchClassTypeByDataType(final String dataType, final int digits) {
        String result = DataBaseConstant.EMPTY;
        if (DataBaseConstant.VARCHAR2.equalsIgnoreCase(dataType)) {
            result = DataBaseConstant.STRING;
        }
        if (DataBaseConstant.NVARCHAR2.equalsIgnoreCase(dataType)) {
            result = DataBaseConstant.STRING;
        } else if (dataType.equalsIgnoreCase(DataBaseConstant.DOUBLE)) {
            result = DataBaseConstant.DOUBLE;
        } else if (DataBaseConstant.NUMBER.equalsIgnoreCase(dataType) && digits == 0) {
            result = DataBaseConstant.INT;
        } else if (DataBaseConstant.NUMBER.equalsIgnoreCase(dataType) && digits != 0) {
            result = DataBaseConstant.DOUBLE;
        } else if (DataBaseConstant.INT.equalsIgnoreCase(dataType)) {
            result = DataBaseConstant.INT;
        } else if (DataBaseConstant.DATE.equalsIgnoreCase(dataType)) {
            result = DataBaseConstant.DATE_;
        } else if (DataBaseConstant.DATE_TIME.equalsIgnoreCase(dataType)) {
            result = DataBaseConstant.DATE_;
        } else if (DataBaseConstant.BLOB_.equalsIgnoreCase(dataType)) {
            result = DataBaseConstant.BLOB_;
        } else if (DataBaseConstant.CLOB.equalsIgnoreCase(dataType)) {
            result = DataBaseConstant.TEXT_;
        }
        return result;
    }

    @Override
    public String dropTableSql(final String tableName) {
        return DataBaseConstant.SQL_DROP + DataBaseConstant.SQL_TABLE + tableName.toLowerCase() + DataBaseConstant.SEMICOLON;
    }

    @Override
    public String getDropColumnSql(final String fieldName) {
        return DataBaseConstant.SQL_DROP + DataBaseConstant.SQL_COLUMN + fieldName.toUpperCase() + DataBaseConstant.SEMICOLON;
    }

    @Override
    public String getColumnCommentSql(final ColumnMeta columnMeta) {
        return DataBaseConstant.SQL_COMMENT + DataBaseConstant.SQL_ON + DataBaseConstant.SQL_COLUMN + columnMeta.getTableName() + DataBaseConstant.DOT + columnMeta.getColumnName() + DataBaseConstant.SQL_IS + DataBaseConstant.SINGLE_QUOTE + columnMeta.getColumnComment() + DataBaseConstant.SINGLE_QUOTE;
    }

    @Override
    public String getSpecialHandle(final ColumnMeta formColumnMeta, final ColumnMeta dataColumnMeta) {
        return null;
    }

    @Override
    public String creatIndexes(final TableIndex tableIndex, final String tableName) {
        StringBuilder sql = new StringBuilder();
        if (!CommonConstant.DEL_FLAG_DELETE.equals(tableIndex.getDelFlag()) && CommonConstant.TO_UPPER_CASE_N.equals(tableIndex.getIsSynchronize())) {
            String indexName = tableIndex.getIndexName();
            String indexField = tableIndex.getIndexField();
            String indexType = DataBaseConstant.NORMAL_SYNCHRONIZATION.equals(tableIndex.getIndexType()) ? DataBaseConstant.SQL_INDEX : tableIndex.getIndexType() + DataBaseConstant.SQL_INDEX;
            sql.append(DataBaseConstant.SQL_CREATE).append(indexType).append(indexName).append(DataBaseConstant.SQL_ON).append(tableName).append(DataBaseConstant.LEFT_BRACKET).append(indexField).append(DataBaseConstant.RIGHT_BRACKET);
        }
        return sql.toString();
    }

    @Override
    public String dropIndexes(final String indexName, final String tableName) {
        return DataBaseConstant.SQL_DROP + DataBaseConstant.SQL_INDEX + indexName;
    }

    @Override
    public String countIndex(final String indexName, final String tableName) {
        return DataBaseConstant.SQL_SELECT + DataBaseConstant.SQL_COUNT + DataBaseConstant.SQL_FROM + "user_ind_columns" + DataBaseConstant.SQL_WHERE + "table_name" + DataBaseConstant.SPACE + DataBaseConstant.EQUALS + DataBaseConstant.SPACE + "upper" + DataBaseConstant.LEFT_BRACKET + DataBaseConstant.SINGLE_QUOTE + indexName + DataBaseConstant.SINGLE_QUOTE + DataBaseConstant.RIGHT_BRACKET;
    }

}
